#include <iostream>
#include <unistd.h>

//关于wait()和waitpid()函数
//父进程调用时，会有以下几种情况
//1、如果子进程还在运行，则阻塞，waitpid()可以设置参数不阻塞
//2、如果有任意一个子进程已经结束了，则会立即返回该进程的pid
//3、如果没有子进程，则返回错误
//4、如果子进程退出后，父进程不调用wait或waitpid函数，子进程会变成僵尸进程，造成pid的浪费

//关于本案例：
//1、fork后父子进程随机进入各自程序
//2、父进程sleep(5)之后，跑到wait阻塞
//3、10s后，子进程退出，同时父进程的wait检测到没有子进程，wait返回-1
//总结，所以要让父进程监听子进程是否结束(来实施wait操作)，防止产生僵尸进程，有两个方案
//方案1、不要一上来就调用wait，让子进程结束的时候通过发出一个信号，让父进程调用wait,父进程调用wait时则会立刻返回
//方案2、使用waitpid()这个函数有个参数可以不阻塞，待研究@todo
int main(){
    pid_t childPid;
    childPid = fork();
    if(childPid < 0){
        std::cout<< "fork失败" << std::endl;
        exit(1);
    }else if(childPid == 0){
        //child
        printf("im child, getpid()=%d\n", getpid());
        sleep(10);
        printf("im child, getpid()=%d, after sleep\n", getpid());
        
        exit(0);
    }else{
        printf("im father, getpid()=%d\n", getpid());
        sleep(4);
        printf("im father, getpid()=%d after sleep\n", getpid());
        //father
        int status = 0;
        pid_t diePid;
        diePid = wait(&status);
        if(diePid < 0){
            printf("waite error :%d, status:%d\n", diePid, status);
        }else{
            printf("my child %d died, status:%d\n", diePid, status);
        }
    }

    

    return 0;
}